package net.sk.pt;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashMap;


import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class StateUtil {
	public final static char keyJoin = '@';
	static private HashMap<String, String[]> cn_keys = new HashMap<String, String[]>();
	static private HashMap<State,Object> somap = new HashMap<State,Object>();
	
	static public Object getso(State sta){
		return somap.get(sta);
	}
	static public void register(String cn, String[] keyProps) {
		cn_keys.put(cn, keyProps);
	}
	static public String[] getCnKey(String cn){
		String[] keys = cn_keys.get(cn);
		if(keys!=null)
			return keys;
		else
			return new String[]{"id"};
	}

	static public String getKey(State sta) {
		String[] kp = getCnKey(sta.getCn());
		HashMap<String, Object> its = sta.getItems();
		StringBuffer sbuf = new StringBuffer(sta.getCn());
		for (int i = 0; i < kp.length; i++) {
			sbuf.append(keyJoin);
			sbuf.append(its.get(kp[i]));
		}
		return sbuf.toString();
	}
	static public String[] listFields(Object obj) {
		BeanInfo info = null;
		try {
			info = Introspector.getBeanInfo(obj.getClass());
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
		String[] ps = new String[descriptors.length - 1];
		int pos = 0;
		for (int i = 0; i < descriptors.length; i++) {
			// 忽略只读属性
			// String pn = descriptors[i].getWriteMethod()==null);
			String pn = descriptors[i].getName();
			if (pn.equals("class"))
				continue;
			ps[pos] = pn;
			pos++;
		}
		return ps;
	}
	static public State obj2sta(Object so, String[] props, char action) {
		// 封装pojo
		BeanWrapper bw = new BeanWrapperImpl(so);
		State sta = new State();
		HashMap<String, Object> sta_its = new HashMap<String, Object>();
		// 如果props未指定,而action为add,则自动获得所有属性名
		if (props == null && action == State.ACTION_ADD)
			props = listFields(so);
		if (props != null) {
			for (int i = 0; i < props.length; i++) {
				String pn = props[i];
				sta_its.put(pn, bw.getPropertyValue(pn));
			}
		}
		String cn = so.getClass().getName();
		// 唯一标示属性是必须的
		sta.setItems(sta_its);
		sta.setAction(action);
		sta.setCn(cn);
		sta.setKey(getKey(sta));
		somap.put(sta, so);
		return sta;
	}

}
